/**
 * @addtogroup assist_shell
 * assist_shell
 * @{
 */
/**
 * @file assist_shell.h
 * @note 线程不安全
 * @author Akee(shengkun.you@hopechart.com)
 * @par 修改日志
 * <table>
 * <tr><th>Date <th>Version <th>Author <th>Description
 * <tr><td>2022-05-07 <td>1.0 <td>Akee <td>创建初始版本
 * <tr><td>2022-05-13 <td>1.1 <td>软件工程院 <td>声明本文件为接口文件
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _ASSIST_SHELL_H_
#define _ASSIST_SHELL_H_

#include <hcc_error_code_mid_assist_shell.h>
#include <ofc_types.h>
#include <ofc_object.h>

#ifdef __cplusplus
extern "C" {
#endif

enum {
    kAssistShellMaxPasswdLen = 16,  ///< 密码长度
    kAssistShellMaxCmdLen = 10,  ///< 最大的命令长度
};

struct TAssistShellCmdTag {
    char cmd[kAssistShellMaxCmdLen];  ///< 命令
    void (*fp)(char argc, char *argv);  ///< 命令执行函数
    char *desc;  ///< 命令描述
};
typedef struct TAssistShellCmdTag TAssistShellCmd;

/// 请自定义全局命令变量
extern const TAssistShellCmd kAssistShellCmd[];

/**
 * 发送数据执行事件
 * @param user_data: 用户数据
 * @param data: 数据地址
 * @param len: 数据大小
 * @return 实际发送数据大小
 */
typedef Int32 (*TAssistShellDoWrite)(void *user_data, const void *data, Int32 len);

/**
 * 接收数据执行事件
 * @param user_data: 用户数据
 * @param buf: 接收数据地址
 * @param len: 接收数据大小
 * @return 实际接收数据大小
 */
typedef Int32 (*TAssistShellDoRead)(void *user_data, void *buf, Int32 len);

/**
 * 获取辅助 shell 版本信息
 * @param version: 版本号整型值, 如: 0x010A020B 表示 1.10.2.11
 * @return 返回字符串的版本信息, 格式: x.x.x.x-yyyy.mm.dd
 */
char *AssistShellVersion(Int32 *version);

/**
 * 辅助shell创建
 * @note -# 主动解析方式,使用
 * @param active: True 表示主动解析方式, False 表示被动解析方式
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellCreate(Bool active);

/**
 * 辅助shell销毁
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellDestroy(void);

/**
 * 设置事件
 * @note -# 必须在 TAssistShellOpen 之前调用
 *       -# 主动解析方式下, do_read 为空
 * @param user_data: 用户数据
 * @param do_write: 发送数据事件
 * @param do_read: 主动解析方式下, do_read 为空
 * @param do_tick: 获取节拍事件
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellSetEvent(void *user_data, TAssistShellDoWrite do_write, TAssistShellDoRead do_read);

/**
 * 设置Shell密码
 * @note -# 必须在 TAssistShellOpen 之前调用
 *       -# 密码可以不进行设置, 当未设置时, 可以直接登录
 *       -# 设置时, 至少要有8位数字，否则失败，不允许为空
 * @param passwd: 密码
 * @param len: 密码长度, 内部最大只截取 kAssistShellMaxPasswordLen 个字节的长度
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellSetPasswd(const char *passwd, Int32 len);

/**
 * 获取Shell密码
 * @param passwd: 密码，内部最大只截取 kAssistShellMaxPasswordLen 个字节的长度
 * @param len: 密码长度，内部最大只截取 kAssistShellMaxPasswordLen 个字节的长度
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellPasswd(char *passwd, Int32 len);

/**
 * 设置超时时间
 * @note -# 必须在 TAssistShellOpen 之前调用
 *       -# 可以不进行设置或者设置为0时, 将永久连接
 *       -# 当一段时间未收到数据，会进行断开，需要通过密码重新登录
 * @param timeout: 超时时间，单位：ms
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellSetTimeout(UInt32 timeout);

/**
 * 获取超时时间
 * @param timeout: 超时时间指针，单位：ms
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellTimeout(UInt32 *timeout);

/**
 * 打开辅助Shell
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellOpen(void);

/**
 * 关闭辅助Shell
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellClose(void);

/**
 * 当前是否登录
 * @param is_login: True: 已登录; False: 未登录
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellIsLogin(Bool *is_login);

/**
 * 辅助shell日志输出
 * @param fmt: 格式化命令字
 * @param ...: 格式化参数
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellLogOut(const char *fmt, ...);

/**
 * 辅助shell 写入数据
 * @note 主动解析方式
 * @param data: 数据指针
 * @param len: 数据长度
 * @param tick: 节拍计数
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellWrite(const char *data, Int32 len, UInt32 tick);

/**
 * 辅助shell 执行体
 * @note -# 被动解析方式
 *       -# 定时调用本函数执行命令解析
 *       -# 建议轮询时间: 10 ms
 * @param data: 数据指针
 * @param len: 数据长度
 * @param tick: 节拍计数
 * @return 当返回值 >= 0 时, 表示成功 \n
 *         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
 */
Int32 AssistShellRunOnce(UInt32 tick);


/**
* 设置密码状态
* @param is_need_password: True: 需要密码; False: 无需密码
* @note: 临时使用，调用完此接口后，仅在超时时间内无需密码，并且自动登入，超时时间后会自动要求继续输入密码
* @return 当返回值 >= 0 时, 表示成功 \n
*         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
*/
Int32 AssistShellSetPasswordState(Bool is_need_password, UInt32 curr_tick);


/**
* 设置是否回显
* @param is_echo: True: 回显; False: 无需回显
* @return 当返回值 >= 0 时, 表示成功 \n
*         当返回值 < 0 时, 表示失败, 参见[assist_shell](@ref TAssistShellErrorCode)
*/
Int32 AssistShellSetIsEcho(Bool is_echo);
#ifdef __cplusplus
} // extern "C" {
#endif

#endif
/**
 * @} 
 */
